package com.dhcc.core.framework.util;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.ZoneId;
import java.util.Calendar;
import java.util.Date;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;

/**
 * 日期工具类
 * 
 * @ClassName: DateUtil
 * @Description: TODO
 * @author: cyf
 * @date: 2018年1月2日 上午9:34:27
 */
public class DateUtil extends DateUtils {

    public static String YYYY = "yyyy";

    public static String YYYY_MM = "yyyy-MM";

    public static String YYYY_MM_DD = "yyyy-MM-dd";

    public static String YYYYMMDD = "yyyyMMdd";

    public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";

    public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";

    public static String HH_MM_SS = "HH:mm:ss";

    private static String[] parsePatterns = { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
            "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM", "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss",
            "yyyy.MM.dd HH:mm", "yyyy.MM" };

    /**
     * 
     * 当前时间，格式 yyyy-MM-dd HH:mm:ss
     * 
     * @return 当前时间的标准形式字符串
     * 
     */
    public static String now() {
        return getTime();
    }

    /**
     * 获取YYYY格式
     *
     * @return
     */
    public static String getYear() {
        return formatDate(new Date(), YYYY);
    }

    /**
     * 获取YYYY格式
     *
     * @return
     */
    public static String getYear(Date date) {
        return formatDate(date, YYYY);
    }

    /**
     * 获取YYYY-MM格式
     *
     * @return
     */
    public static String getYearMonth() {
        return formatDate(new Date(), YYYY_MM);
    }

    /**
     * 获取YYYY-MM格式
     *
     * @return
     */
    public static String getYearMonth(Date date) {
        return formatDate(date, YYYY_MM);
    }

    /**
     * 获取YYYY-MM-DD格式
     *
     * @return
     */
    public static String getDay() {
        return formatDate(new Date(), YYYY_MM_DD);
    }

    /**
     * 获取YYYY-MM-DD格式
     *
     * @return
     */
    public static String getDay(Date date) {
        return formatDate(date, YYYY_MM_DD);
    }

    /**
     * 获取YYYYMMDD格式
     *
     * @return
     */
    public static String getDays() {
        return formatDate(new Date(), YYYYMMDD);
    }

    /**
     * 获取YYYYMMDD格式
     *
     * @return
     */
    public static String getDays(Date date) {
        return formatDate(date, YYYYMMDD);
    }

    /**
     * 获取YYYY-MM-DD HH:mm:ss格式
     *
     * @return
     */
    public static String getTime() {
        return formatDate(new Date(), YYYY_MM_DD_HH_MM_SS);
    }

    /**
     * 获取HH:mm:ss格式
     *
     * @return
     */
    public static String getOnlyTime(Date date) {
        return formatDate(date, HH_MM_SS);
    }

    /**
     * 获取YYYY-MM-DD HH:mm:ss.SSS格式
     *
     * @return
     */
    public static String getMsTime() {
        return formatDate(new Date(), "yyyy-MM-dd HH:mm:ss.SSS");
    }

    /**
     * 获取YYYYMMDDHHmmss格式
     *
     * @return
     */
    public static String getAllTime() {
        return formatDate(new Date(), YYYYMMDDHHMMSS);
    }

    /**
     * 获取YYYY-MM-DD HH:mm:ss格式
     *
     * @return
     */
    public static String getTime(Date date) {
        return formatDate(date, YYYY_MM_DD_HH_MM_SS);
    }
    
    /**
     * 获取YYYYMMDDHHmmss格式
     *
     * @return
     */
    public static String getTimes(Date date) {
        return formatDate(date, YYYYMMDDHHMMSS);
    }

    public static String formatDate(Date date, String pattern) {
        String formatDate = null;
        if (StringUtils.isNotBlank(pattern)) {
            formatDate = DateFormatUtils.format(date, pattern);
        } else {
            formatDate = DateFormatUtils.format(date, YYYY_MM_DD);
        }
        return formatDate;
    }

    /**
     * @Title: compareDate
     * @Description:(日期比较，如果s>=e 返回true 否则返回false)
     * @param s
     * @param e
     * @return boolean
     * @throws @author
     *             luguosui
     */
    public static boolean compareDate(String s, String e) {
        if (parseDate(s) == null || parseDate(e) == null) {
            return false;
        }
        return parseDate(s).getTime() >= parseDate(e).getTime();
    }

    /**
     * 格式化日期
     *
     * @return
     */
    public static Date parseDate(String date) {
        return parse(date, YYYY_MM_DD);
    }

    /**
     * 格式化日期
     *
     * @return
     */
    public static Date parseTime(String date) {
        return parse(date, YYYY_MM_DD_HH_MM_SS);
    }

    /**
     * 格式化日期
     *
     * @return
     */
    public static Date parse(String date, String pattern) {
        try {
            return DateUtils.parseDate(date, pattern);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 格式化日期
     *
     * @return
     */
    public static String format(Date date, String pattern) {
        return DateFormatUtils.format(date, pattern);
    }

    /**
     * 把日期转换为Timestamp
     *
     * @param date
     * @return
     */
    public static Timestamp format(Date date) {
        return new Timestamp(date.getTime());
    }

    /**
     * 校验日期是否合法
     *
     * @return
     */
    public static boolean isValidDate(String s) {
        return parse(s, YYYY_MM_DD_HH_MM_SS) != null;
    }

    /**
     * 校验日期是否合法
     *
     * @return
     */
    public static boolean isValidDate(String s, String pattern) {
        return parse(s, pattern) != null;
    }

    public static int getDiffYear(String startTime, String endTime) {
        DateFormat fmt = new SimpleDateFormat(YYYY_MM_DD);
        try {
            int years = (int) (((fmt.parse(endTime).getTime() - fmt.parse(startTime).getTime()) / (1000 * 60 * 60 * 24))
                    / 365);
            return years;
        } catch (Exception e) {
            // 如果throw java.text.ParseException或者NullPointerException，就说明格式不对
            return 0;
        }
    }

    /**
     * <li>功能描述：时间相减得到天数
     *
     * @param beginDateStr
     * @param endDateStr
     * @return long
     * @author Administrator
     */
    public static long getDaySub(String beginDateStr, String endDateStr) {
        long day = 0;
        SimpleDateFormat format = new SimpleDateFormat(YYYY_MM_DD);
        Date beginDate = null;
        Date endDate = null;

        try {
            beginDate = format.parse(beginDateStr);
            endDate = format.parse(endDateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        day = (endDate.getTime() - beginDate.getTime()) / (24 * 60 * 60 * 1000);
        // System.out.println("相隔的天数="+day);

        return day;
    }

    /**
     * 得到n天之后的日期
     *
     * @param days
     * @return
     */
    public static String getAfterDayDate(String days) {
        int daysInt = Integer.parseInt(days);

        Calendar canlendar = Calendar.getInstance(); // java.util包
        canlendar.add(Calendar.DATE, daysInt); // 日期减 如果不够减会将月变动
        Date date = canlendar.getTime();

        SimpleDateFormat sdfd = new SimpleDateFormat(YYYY_MM_DD_HH_MM_SS);
        String dateStr = sdfd.format(date);

        return dateStr;
    }

    /**
     * 得到n天之后是周几
     *
     * @param days
     * @return
     */
    public static String getAfterDayWeek(String days) {
        int daysInt = Integer.parseInt(days);

        Calendar canlendar = Calendar.getInstance(); // java.util包
        canlendar.add(Calendar.DATE, daysInt); // 日期减 如果不够减会将月变动
        Date date = canlendar.getTime();

        SimpleDateFormat sdf = new SimpleDateFormat("E");
        String dateStr = sdf.format(date);

        return dateStr;
    }

    /**
     * 日期型字符串转化为日期 格式
     */
    public static Date parse(Object str) {
        if (str == null) {
            return null;
        }
        try {
            return parseDate(str.toString(), parsePatterns);
        } catch (ParseException e) {
            return null;
        }
    }
    
    /** 
     * 获取任意时间的月的最后一天 
     * 描述:<描述函数实现的功能>. 
     * @param 
     * @return YYYY-MM-DD
     */ 
	public static String getMaxMonthDate(Date date) { 
        Calendar calendar = Calendar.getInstance(); 
        calendar.setTime(date); 
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH)); 
        return formatDate(calendar.getTime(),YYYY_MM_DD);
    } 
     
    /** 
     * 获取任意时间的月第一天 
     * 描述:<描述函数实现的功能>. 
     * @param date
     * @return YYYY-MM-DD
     */ 
    public static String getMinMonthDate(Date date){ 
        Calendar calendar = Calendar.getInstance(); 
        calendar.setTime(date); 
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH)); 
        return formatDate(calendar.getTime(),YYYY_MM_DD);
    } 
    
    /**
     * @Description: 获取n个月前的第一天 n为负如-1为上一个月 n为正如1为下一个月
     * @Title: getLastMaxMonthDate   
     * @return: String  YYYY-MM-DD    
     * @author: wujiafeng
     * @date:2020年5月14日 上午10:38:22
     */
    public static String getMinMonthDate(int diffMonth) { 
        Calendar calendar = Calendar.getInstance(); 
        calendar.setTime(new Date()); 
        calendar.add(Calendar.MONTH, diffMonth); 
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH)); 
        return formatDate(calendar.getTime(),YYYY_MM_DD);
    } 

    /**
     * @Description: 获取n个月前的最后一天 n为负如-1为上一个月 n为正如1为下一个月
     * @Title: getMaxMonthDate   
     * @return: String  YYYY-MM-DD
     * @author: wujiafeng
     * @date:2020年5月14日 上午10:41:20
     */
    public static String getMaxMonthDate(int diffMonth) { 
        Calendar calendar = Calendar.getInstance(); 
        calendar.setTime(new Date()); 
        calendar.add(Calendar.MONTH, diffMonth); 
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH)); 
        return formatDate(calendar.getTime(),YYYY_MM_DD);
    }

    /**
     * @Description: 判断两个时间是否超过24小时
     * @Title: getDateSub
     * @return: boolean
     * @author: sunyingjie
     * @date:2020年9月30日 上午10:41:20
     */
    public static boolean getDateSub(String date1, String date2) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            Date start = sdf.parse(date1);
            Date end = sdf.parse(date2);
            long cha = end.getTime() - start.getTime();
            double result = cha * 1.0 / (1000 * 60 * 60);
            if(result<=24){
                return false; //说明小于24小时
            }else{
                return true;
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 将 java.util.Date 转换为 LocalDate。
     *
     * @param date 日期
     * @return LocalDate
     */
    private static LocalDate dateToLocalDate(Date date) {
        // 使用 ZonedDateTime 作为中间转换
        return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
    }

    /**
     * 判断两个日期是否在同一季度并且属于同一年。
     *
     * @param date1 第一个日期
     * @param date2 第二个日期
     * @return 如果两个日期在同一季度并且属于同一年返回 true，否则返回 false
     */
    public static boolean isSameQuarter(Date date1, Date date2) {
        LocalDate localDate1 = dateToLocalDate(date1);
        LocalDate localDate2 = dateToLocalDate(date2);

        // 检查是否属于同一年
        if (localDate1.getYear() != localDate2.getYear()) {
            return false;
        }

        // 检查是否在同一季度
        YearMonth yearMonth1 = YearMonth.from(localDate1);
        YearMonth yearMonth2 = YearMonth.from(localDate2);

        return yearMonth1.getMonthValue() / 3 == yearMonth2.getMonthValue() / 3;
    }

}
